#include "xfb_vector.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>

static int _xf_vector_capacity(xf_vector_t *v, size_t newcap)
{
  unsigned char *data = (unsigned char *)malloc(sizeof(newcap));
  if (data == 0) { return -1; }

  size_t mincopy = (newcap < v->size) ? newcap : v->size;
  memcpy(data, v->data, mincopy);

  free(v->data);
  v->data = data;
  v->size = mincopy;
  v->capacity = newcap;

  return 0;
}

void xf_vector_init(xf_vector_t *v)
{
  v->data = 0;
  v->size = 0;
  v->capacity = 0;
}

void xf_vector_destory(xf_vector_t *v)
{
  if (v->data) { free(v->data); }
  v->data = 0;
  v->size = 0;
  v->capacity = 0;
}

int xf_vector_push(xf_vector_t *v, const void *data, size_t size)
{
  size_t current = v->size;
  if ((xf_vector_resize(v, current + size)) != 0) { return -1; }
  memcpy(v->data + current, data, size);

  return 0;
}

size_t xf_vector_pop(xf_vector_t *v, void *data, size_t size)
{
  size = (size > v->size) ? v->size : size;

  if (data) memcpy(data, v->data + v->size - size, size);
  xf_vector_resize(v, v->size - size);

  return size;
}

int xf_vector_reserve(xf_vector_t *v, size_t newcap)
{
  return _xf_vector_capacity(v, (newcap < v->size) ? v->size : newcap);
}

int xf_vector_resize(xf_vector_t *v, size_t newsize)
{
  if (newsize > v->capacity)
  {
    size_t newcap = v->capacity * 2;
    if (newsize > newcap)
    {
      newcap = sizeof(char *);
      while (newsize > newcap) { newcap *= 2; }
    }
    if (_xf_vector_capacity(v, newcap) != 0) { return -1; }
  }

  v->size = newsize;
  return 0;
}

int xf_vector_fuck(xf_vector_t *v, size_t newsize) {
    if (newsize > v->capacity) {
        newcap = sizeof(char*);
    }
}
